home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / pascal / pars7.exe / BUILDER.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1993-04-29  |  35.5 KB  |  1,203 lines

  1. unit builder;
  2. {$O+,F+}
  3. interface
  4. uses realtype,pars7glb;
  5.  
  6. procedure parsefunction(s:string;var fop:operationpointer;
  7.             var pointx,pointy,pointt,a,b,c,d,e:rpointer;var numop:integer;
  8.            var error:boolean; showprogress:boolean);
  9. implementation
  10.  
  11. type sstring=string;
  12.  
  13.      termsorttype=(variab,constant,brack,minus,sum,diff,prod,divis,
  14.                     intpower,realpower,cosine,sine,expo,logar,sqroot,arctang,
  15.                     square,third,forth,abso,maxim,minim,heavi,
  16.                     phase,randfunc,argu,hypersine,hypercosine,radius,
  17.                     randrand);
  18.  
  19. procedure chopblanks(var s:sstring);  forward;
  20. {deletes all blanks in s}
  21.  
  22. procedure checkbracketnum(s:sstring; var result:boolean); forward;
  23. {checks whether # of '(' equ. # of ')'}
  24.  
  25. procedure checknum(s:sstring;var num:float;var result:boolean); forward;
  26. {checks whether s is a number}
  27.  
  28. procedure checkvar(s:sstring;var varsort:word;var result:boolean); forward;
  29. {checks whether s is a variable string}
  30.  
  31. procedure checkparam(s:sstring;var parsort:word;var result:boolean); forward;
  32. {checks whether s is a parameter string}
  33.  
  34. procedure checkbrack(s:sstring;var s1:sstring;var result:boolean); forward;
  35. {checks whether s =(...(s1)...) and s1 is a valid term}
  36.  
  37. procedure checkmin(s:sstring;var s1:sstring;var result:boolean); forward;
  38. {checks whether s denotes the negative value of a valid operation}
  39.  
  40. procedure checksum(s:sstring;var s1,s2:sstring;var result:boolean); forward;
  41. {checks whether '+' is the primary operation in s}
  42.  
  43. procedure checkdiff(s:sstring;var s1,s2:sstring;var result:boolean); forward;
  44. {checks whether '-' is the primary operation in s}
  45.  
  46. procedure checkprod(s:sstring;var s1,s2:sstring;var result:boolean); forward;
  47. {checks whether '*' is the primary operation in s}
  48.  
  49. procedure checkdiv(s:sstring;var s1,s2:sstring;var result:boolean);  forward;
  50. {checks whether '/' is the primary operation in s}
  51.  
  52. procedure check2varfunct(s:sstring;var s1,s2:sstring;var fsort:
  53.     termsorttype;var result:boolean);  forward;
  54. {checks whether s=f(s1,s2); s1,s2 being valid terms}
  55.  
  56. procedure checkfunct(s:sstring;var s1:sstring;var fsort:termsorttype;
  57. var result:boolean); forward;
  58. {checks whether s denotes the evaluation of a function fsort(s1)}
  59.  
  60. procedure checkintpower(s:sstring;var s1,s2:sstring;var result:boolean); forward;
  61. {checks whether s=s1^s2, s2 integer}
  62.  
  63. procedure checkrealpower(s:sstring;var s1,s2:sstring;var result:boolean); forward;
  64. {checks whether s=s1^s2, s2 real}
  65.  
  66. procedure chopblanks(var s:sstring);
  67. var i:byte;
  68. begin
  69.   while pos(' ',s)>0 do
  70.   begin
  71.     i:=pos(' ',s);
  72.     delete(s,i,1);
  73.   end;
  74. end;
  75.  
  76. procedure checkbracketnum(s:sstring; var result:boolean);
  77. var lauf,lzu,i:integer;
  78. begin
  79.   lauf:=0;lzu:=0;i:=0;
  80.   result:=false;
  81.   repeat
  82.     i:=i+1;
  83.     if copy(s,i,1)='(' then
  84.       lauf:=lauf+1;
  85.     if copy(s,i,1)=')' then
  86.       lzu:=lzu+1;
  87.   until i>=length(s);
  88.   if lauf=lzu then
  89.     result:=true;
  90. end;
  91.  
  92. procedure checknum(s:sstring;var num:float;var result:boolean);
  93. var code,p,i:integer;  n:longint; num1:float;  s1,s2:sstring;
  94. begin
  95.   result:=false;
  96.   if s='Pi' then
  97.   begin
  98.     result:=true;
  99.     num:=Pi;
  100.     exit;
  101.   end
  102.   else
  103.   begin
  104.     val(s,num,code);
  105.     if code=0 then
  106.       result:=true;
  107.   end;
  108. end;
  109.  
  110. procedure checkparam(s:sstring; var parsort:word; var result:boolean);
  111. begin
  112.   result:=false;
  113.   if length(s)<>1 then exit else
  114.   begin
  115.     if s='A' then begin
  116.       result:=true; parsort:=1; exit; end;
  117.     if s='B' then begin
  118.       result:=true; parsort:=2; exit; end;
  119.     if s='C' then begin
  120.       result:=true; parsort:=3; exit; end;
  121.     if s='D' then begin
  122.       result:=true; parsort:=4; exit; end;
  123.     if s='E' then begin
  124.       result:=true; parsort:=5; exit; end;
  125.   end;
  126. end;
  127.  
  128.  
  129. procedure checkvar(s:sstring;var varsort:word;var result:boolean);
  130. begin
  131.   result:=false;
  132.   if length(s)<>1 then exit else
  133.   begin
  134.     if s='x' then
  135.     begin
  136.       result:=true;
  137.       varsort:=1;
  138.       exit;
  139.     end;
  140.     if s='y' then
  141.     begin
  142.       result:=true;
  143.       varsort:=2;
  144.       exit;
  145.     end;
  146.     if s='t' then
  147.     begin
  148.       result:=true;
  149.       varsort:=3;
  150.       exit;
  151.     end;
  152.   end;
  153. end;
  154.  
  155.  
  156.  
  157. procedure checkbrack(s:sstring;var s1:sstring;var result:boolean);
  158. var s2,s3:sstring;   num:float;  fsort:termsorttype; varsort:word;
  159. begin
  160.   result:=false;
  161.   if copy(s,1,1)='(' then
  162.     if copy(s,length(s),1)=')' then
  163.     begin
  164.       s1:=copy(s,2,length(s)-2);
  165.       checksum(s1,s2,s3,result); if result then exit;
  166.       checknum(s1,num,result); if result then exit;
  167.       checkdiff(s1,s2,s3,result); if result then exit;
  168.       checkmin(s1,s2,result);if result then exit;
  169.       checkprod(s1,s2,s3,result);if result then exit;
  170.       checkdiv(s1,s2,s3,result);if result then exit;
  171.       check2varfunct(s1,s2,s3,fsort,result);if result then exit;
  172.       checkfunct(s1,s2,fsort,result);if result then exit;
  173.       checkvar(s1,varsort,result);if result then exit;
  174.       checkparam(s1,varsort,result);if result then exit;
  175.       checkintpower(s1,s2,s3,result);if result then exit;
  176.       checkrealpower(s1,s2,s3,result);if result then exit;
  177.       checkbrack(s1,s2,result);
  178.       if result then begin s1:=s2;  exit; end;
  179.     end;
  180. end;
  181.  
  182. procedure checkmin(s:sstring;var s1:sstring;var result:boolean);
  183. var s2,s3:sstring;  num:float;   fsort:termsorttype; varsort:word;
  184. begin
  185.   result:=false;
  186.   if copy(s,1,1)='-' then
  187.   begin
  188.     s1:=copy(s,2,length(s)-1);
  189.     checkbrack(s1,s2,result);
  190.     if result then begin
  191.       s1:=s2;  exit; end;
  192.     checkvar(s1,varsort,result); if result then exit;
  193.     checkparam(s1,varsort,result); if result then exit;
  194.     checkfunct(s1,s2,fsort,result); if result then exit;
  195.     check2varfunct(s1,s2,s3,fsort,result); if result then exit;
  196.     checkintpower(s1,s2,s3,result); if result then exit;
  197.     checkrealpower(s1,s2,s3,result); if result then exit;
  198.   end;
  199. end;
  200.  
  201. procedure checksum(s:sstring;var s1,s2:sstring;var result:boolean);
  202. var s3,s4:sstring; i,j:byte; num:float;    fsort:termsorttype;varsort:word;
  203. begin
  204.   result:=false;
  205.   i:=0;
  206.   repeat
  207.     j:=pos('+',copy(s,i+1,length(s)-i));
  208.     if j>0 then
  209.     begin
  210.       i:=i+j;
  211.       if (i<length(s)) and (i>1) then
  212.       begin
  213.         s1:=copy(s,1,i-1);  s2:=copy(s,i+1,length(s)-i);
  214.         checkbracketnum(s1,result); if result then
  215.           checkbracketnum(s2,result); if result then
  216.         begin
  217.           checkvar(s1,varsort,result);
  218.           if not result then
  219.           checknum(s1,num,result);
  220.           if not result then
  221.           checkparam(s1,varsort,result);
  222.           if not result then
  223.           begin
  224.           checkbrack(s1,s3,result);
  225.           if result then s1:=s3; end;
  226.           if not result then
  227.           checkmin(s1,s3,result);
  228.           if not result then
  229.           checkdiff(s1,s3,s4,result);
  230.           if not result then
  231.           checkprod(s1,s3,s4,result);
  232.           if not result then
  233.           checkdiv(s1,s3,s4,result);
  234.           if not result then
  235.           check2varfunct(s1,s3,s4,fsort,result);
  236.           if not result then
  237.           checkfunct(s1,s3,fsort,result);
  238.           if not result then
  239.           checkintpower(s1,s3,s4,result);
  240.           if not result then
  241.             checkrealpower(s1,s3,s4,result);
  242.           if result then
  243.           begin
  244.             checkvar(s2,varsort,result); if result then exit;
  245.               checknum(s2,num,result);if result then exit;
  246.               checkparam(s2,varsort,result); if result then exit;
  247.               checkbrack(s2,s3,result);
  248.               if result then begin
  249.                 s2:=s3; exit; end;
  250.               checksum(s2,s3,s4,result);if result then exit;
  251.               checkdiff(s2,s3,s4,result);if result then exit;
  252.               checkprod(s2,s3,s4,result);if result then exit;
  253.               checkdiv(s2,s3,s4,result);if result then exit;
  254.               checkfunct(s2,s3,fsort,result);if result then exit;
  255.               check2varfunct(s2,s3,s4,fsort,result);if result then exit;
  256.               checkintpower(s2,s3,s4,result);if result then exit;
  257.               checkrealpower(s2,s3,s4,result);if result then exit;
  258.           end;
  259.         end;
  260.       end;
  261.     end;
  262.   until result or (i>=length(s)) or (j=0);
  263. end;
  264.  
  265. procedure checkdiff(s:sstring;var s1,s2:sstring;var result:boolean);
  266. var s3,s4:sstring; i,j:integer;  num:float;   fsort:termsorttype;varsort:word;
  267. begin
  268.   result:=false;
  269.   i:=0;
  270.   repeat
  271.     j:=pos('-',copy(s,i+1,length(s)-i));
  272.     if j>0 then
  273.     begin
  274.     i:=i+j;
  275.     if (i<length(s)) and (i>1) then
  276.     begin
  277.       s1:=copy(s,1,i-1);  s2:=copy(s,i+1,length(s)-i);
  278.       checkbracketnum(s1,result);
  279.       if result then
  280.         checkbracketnum(s2,result);
  281.       if result then
  282.       begin
  283.       checkvar(s1,varsort,result);
  284.       if not result then
  285.         checknum(s1,num,result);
  286.       if not result then
  287.         checkparam(s1,varsort,result);
  288.       if not result then
  289.       begin
  290.         checkbrack(s1,s3,result);
  291.         if result then
  292.           s1:=s3;
  293.       end;
  294.       if not result then
  295.         checkmin(s1,s3,result);
  296.       if not result then
  297.         checkdiff(s1,s3,s4,result);
  298.       if not result then
  299.         checkprod(s1,s3,s4,result);
  300.       if not result then
  301.         checkdiv(s1,s3,s4,result);
  302.       if not result then
  303.              check2varfunct(s1,s3,s4,fsort,result);
  304.       if not result then
  305.         checkfunct(s1,s3,fsort,result);
  306.       if not result then
  307.         checkintpower(s1,s3,s4,result);
  308.       if not result then
  309.         checkrealpower(s1,s3,s4,result);
  310.       if result then
  311.       begin
  312.         checkvar(s2,varsort,result); if result then exit;
  313.           checknum(s2,num,result);if result then exit;
  314.           checkparam(s2,varsort,result);if result then exit;
  315.           checkbrack(s2,s3,result);
  316.           if result then  begin
  317.             s2:=s3; exit; end;
  318.           checkprod(s2,s3,s4,result);if result then exit;
  319.           checkdiv(s2,s3,s4,result);if result then exit;
  320.          checkfunct(s2,s3,fsort,result);if result then exit;
  321.           check2varfunct(s2,s3,s4,fsort,result);if result then exit;
  322.          checkintpower(s2,s3,s4,result);if result then exit;
  323.          checkrealpower(s2,s3,s4,result);if result then exit;
  324.         end;
  325.       end;
  326.     end;
  327.     end;
  328.   until result or (i>=length(s)) or (j=0);
  329. end;
  330.  
  331. procedure checkprod(s:sstring;var s1,s2:sstring;var result:boolean);
  332. var s3,s4:sstring; i,j:integer;    num:float;    fsort:termsorttype;varsort:word;
  333. begin
  334.   result:=false;
  335.   i:=0;
  336.   repeat
  337.     j:=pos('*',copy(s,i+1,length(s)-i));
  338.     if j>0 then
  339.     begin
  340.       i:=i+j;
  341.     if (i<length(s)) and (i>1) then
  342.     begin
  343.       s1:=copy(s,1,i-1);  s2:=copy(s,i+1,length(s)-i);
  344.       checkbracketnum(s1,result);
  345.       if result then
  346.         checkbracketnum(s2,result);
  347.       if result then
  348.       begin
  349.       checkvar(s1,varsort,result);
  350.       if not result then
  351.         checknum(s1,num,result);
  352.       if not result then
  353.         checkparam(s1,varsort,result);
  354.       if not result then
  355.       begin
  356.         checkbrack(s1,s3,result);
  357.         if result then
  358.             s1:=s3;
  359.       end;
  360.       if not result then
  361.         checkmin(s1,s3,result);
  362.       if not result then
  363.         checkdiv(s1,s3,s4,result);
  364.       if not result then
  365.         checkfunct(s1,s3,fsort,result);
  366.       if not result then
  367.              check2varfunct(s1,s3,s4,fsort,result);
  368.       if not result then
  369.        checkintpower(s1,s3,s4,result);
  370.       if not result then
  371.        checkrealpower(s1,s3,s4,result);
  372.       if result then
  373.       begin
  374.         checkvar(s2,varsort,result); if result then exit;
  375.           checknum(s2,num,result);if result then exit;
  376.           checkparam(s2,varsort,result); if result then exit;
  377.           checkbrack(s2,s3,result);
  378.           if result then begin
  379.             s2:=s3; exit; end;
  380.           checkprod(s2,s3,s4,result);if result then exit;
  381.           checkdiv(s2,s3,s4,result);if result then exit;
  382.          checkfunct(s2,s3,fsort,result);if result then exit;
  383.          check2varfunct(s2,s3,s4,fsort,result);if result then exit;
  384.          checkintpower(s2,s3,s4,result);if result then exit;
  385.          checkrealpower(s2,s3,s4,result);if result then exit;
  386.       end;
  387.       end;
  388.     end;
  389.     end;
  390.   until result or (i>=length(s)) or (j=0);
  391. end;
  392.  
  393. procedure checkdiv(s:sstring;var s1,s2:sstring;var result:boolean);
  394. var s3,s4:sstring; i,j:integer;  varsort:word; num:float; fsort:termsorttype;
  395. begin
  396.   result:=false;
  397.   i:=0;
  398.   repeat
  399.     j:=pos('/',copy(s,i+1,length(s)-i));
  400.     if j>0 then
  401.     begin
  402.       i:=i+j;
  403.     if (i<length(s)) and (i>1) then
  404.     begin
  405.       s1:=copy(s,1,i-1);  s2:=copy(s,i+1,length(s)-i);
  406.       checkbracketnum(s1,result);
  407.       if result then
  408.         checkbracketnum(s2,result);
  409.       if result then
  410.       begin
  411.       checkvar(s1,varsort,result);
  412.       if not result then
  413.         checknum(s1,num,result);
  414.       if not result then
  415.         checkparam(s1,varsort,result);
  416.       if not result then
  417.       begin
  418.         checkbrack(s1,s3,result);
  419.         if result then
  420.             s1:=s3;
  421.       end;
  422.       if not result then
  423.         checkmin(s1,s3,result);
  424.       if not result then
  425.         checkdiv(s1,s3,s4,result);
  426.       if not result then
  427.          checkfunct(s1,s3,fsort,result);
  428.       if not result then
  429.              check2varfunct(s1,s3,s4,fsort,result);
  430.       if not result then
  431.          checkintpower(s1,s3,s4,result);
  432.       if not result then
  433.          checkrealpower(s1,s3,s4,result);
  434.       if result then
  435.       begin
  436.         checkvar(s2,varsort,result); if result then exit;
  437.           checknum(s2,num,result);if result then exit;
  438.         checkparam(s2,varsort,result); if result then exit;
  439.           checkbrack(s2,s3,result);
  440.           if result then  begin
  441.             s2:=s3;  exit; end;
  442.          checkfunct(s2,s3,fsort,result);if result then exit;
  443.              check2varfunct(s2,s3,s4,fsort,result);if result then exit;
  444.          checkintpower(s2,s3,s4,result);if result then exit;
  445.          checkrealpower(s2,s3,s4,result);if result then exit;
  446.       end;
  447.       end;
  448.     end;
  449.     end;
  450.   until result or (i>=length(s)) or (j=0);
  451. end;
  452.  
  453. procedure check2varfunct(s:sstring;var s1,s2:sstring;var fsort:termsorttype;var result:boolean);
  454.   procedure checkcomma(s:sstring;var s1,s2:sstring; var result:boolean);
  455.   var s3:sstring; i,j:integer;
  456.   begin
  457.     result:=false;
  458.     i:=0;
  459.     repeat
  460.       j:=pos(',',copy(s,i+1,length(s)-i));
  461.       if j>0 then
  462.       begin
  463.         i:=i+j;
  464.         if (i<length(s)) and (i>1) then
  465.         begin
  466.           s1:=copy(s,1,i-1);  s2:=copy(s,i+1,length(s)-i);
  467.           s3:='('+s1+')';
  468.           checkbrack(s3,s1,result);
  469.           if result then
  470.           begin
  471.             s3:='('+s2+')';
  472.             checkbrack(s3,s2,result);
  473.           end;
  474.         end;
  475.       end;
  476.     until result or (i>=length(s)) or (j=0);
  477.   end;
  478. var ss:sstring;
  479. begin
  480.   result:=false;
  481.   if copy(s,1,3)='min' then
  482.   begin
  483.     ss:=copy(s,4,length(s)-3);
  484.     if (ss[1]='(') and (ss[length(ss)]=')') then
  485.     begin
  486.       ss:=copy(ss,2,length(ss)-2);
  487.       checkcomma(ss,s1,s2,result);
  488.     end;
  489.     if result then begin fsort:=minim; exit; end;
  490.   end;
  491.   if copy(s,1,3)='max' then
  492.   begin
  493.     ss:=copy(s,4,length(s)-3);
  494.     if (ss[1]='(') and (ss[length(ss)]=')') then
  495.     begin
  496.       ss:=copy(ss,2,length(ss)-2);
  497.       checkcomma(ss,s1,s2,result);
  498.     end;
  499.     if result then begin fsort:=maxim; exit; end;
  500.   end;
  501.   if copy(s,1,2)='rn' then
  502.   begin
  503.     ss:=copy(s,3,length(s)-2);
  504.     if (ss[1]='(') and (ss[length(ss)]=')') then
  505.     begin
  506.       ss:=copy(ss,2,length(ss)-2);
  507.       checkcomma(ss,s1,s2,result);
  508.     end;
  509.     if result then begin fsort:=randfunc; exit; end;
  510.   end;
  511.   if copy(s,1,3)='arg' then
  512.   begin
  513.     ss:=copy(s,4,length(s)-3);
  514.     if (ss[1]='(') and (ss[length(ss)]=')') then
  515.     begin
  516.       ss:=copy(ss,2,length(ss)-2);
  517.       checkcomma(ss,s1,s2,result);
  518.     end;
  519.     if result then begin fsort:=argu; exit; end;
  520.   end;
  521.   if copy(s,1,1)='r' then
  522.   begin
  523.     ss:=copy(s,2,length(s)-1);
  524.     if (ss[1]='(') and (ss[length(ss)]=')') then
  525.     begin
  526.       ss:=copy(ss,2,length(ss)-2);
  527.       checkcomma(ss,s1,s2,result);
  528.     end;
  529.     if result then begin fsort:=radius; exit; end;
  530.   end;
  531.   if copy(s,1,2)='rm' then
  532.   begin
  533.     ss:=copy(s,3,length(s)-1);
  534.     if (ss[1]='(') and (ss[length(ss)]=')') then
  535.     begin
  536.       ss:=copy(ss,2,length(ss)-2);
  537.       checkcomma(ss,s1,s2,result);
  538.     end;
  539.     if result then begin fsort:=randrand; exit; end;
  540.   end;
  541.  
  542. end;
  543.  
  544.  
  545. procedure checkfunct(s:sstring;var s1:sstring;var fsort:termsorttype;var result:boolean);
  546. var s2,s3,s4:sstring; i,j:integer; num:float; ffsort:termsorttype;varsort:word;
  547. begin
  548.   result:=false;
  549.   if copy(s,1,3)='cos' then
  550.   begin
  551.     s2:=copy(s,4,length(s)-3);
  552.     checkbrack(s2,s1,result);
  553.     if result then
  554.       begin fsort:=cosine; exit; end;
  555.   end;
  556.   if copy(s,1,3)='sin' then
  557.   begin
  558.     s2:=copy(s,4,length(s)-3);
  559.     checkbrack(s2,s1,result);
  560.     if result then
  561.       begin fsort:=sine; exit; end;
  562.   end;
  563.   if copy(s,1,3)='exp' then
  564.   begin
  565.     s2:=copy(s,4,length(s)-3);
  566.     checkbrack(s2,s1,result);
  567.     if result then
  568.       begin fsort:=expo; exit; end;
  569.   end;
  570.   if copy(s,1,2)='ln' then
  571.   begin
  572.     s2:=copy(s,3,length(s)-2);
  573.     checkbrack(s2,s1,result);
  574.     if result then
  575.       begin fsort:=logar; exit; end;
  576.   end;
  577.   if copy(s,1,6)='arctan' then
  578.   begin
  579.     s2:=copy(s,7,length(s)-6);
  580.     checkbrack(s2,s1,result);
  581.     if result then
  582.       begin fsort:=arctang; exit; end;
  583.   end;
  584.   if copy(s,1,4)='sqrt' then
  585.   begin
  586.     s2:=copy(s,5,length(s)-4);
  587.     checkbrack(s2,s1,result);
  588.     if result then
  589.       begin fsort:=sqroot; exit; end;
  590.   end;
  591.   if copy(s,1,3)='abs' then
  592.   begin
  593.     s2:=copy(s,4,length(s)-3);
  594.     checkbrack(s2,s1,result);
  595.     if result then
  596.       begin fsort:=abso; exit; end;
  597.   end;
  598.   if copy(s,1,4)='heav' then
  599.   begin
  600.     s2:=copy(s,5,length(s)-4);
  601.     checkbrack(s2,s1,result);
  602.     if result then
  603.       begin fsort:=heavi; exit; end;
  604.   end;
  605.   if copy(s,1,2)='ph' then
  606.   begin
  607.     s2:=copy(s,3,length(s)-2);
  608.     checkbrack(s2,s1,result);
  609.     if result then begin fsort:=phase; exit; end;
  610.   end;
  611.   if copy(s,1,4)='sinh' then
  612.   begin
  613.     s2:=copy(s,5,length(s)-4);
  614.     checkbrack(s2,s1,result);
  615.     if result then begin fsort:=hypersine; exit; end;
  616.   end;
  617.   if copy(s,1,4)='cosh' then
  618.   begin
  619.     s2:=copy(s,5,length(s)-4);
  620.     checkbrack(s2,s1,result);
  621.     if result then begin fsort:=hypercosine; exit; end;
  622.   end;
  623.   if not result then
  624.   begin
  625.     i:=0;
  626.     repeat
  627.       j:=pos('^',copy(s,i+1,length(s)-i));
  628.       if j>0 then
  629.       begin
  630.       i:=i+j;
  631.       if (1<i) and (i<length(s)) then
  632.       begin
  633.         s1:=copy(s,1,i-1);
  634.         s2:=copy(s,i+1,length(s)-i);
  635.         checkbracketnum(s1,result);
  636.         if result then
  637.           checkbracketnum(s2,result);
  638.         if result then
  639.         begin
  640.           checkvar(s1,varsort,result);
  641.           if not result then
  642.           begin
  643.             checkbrack(s1,s3,result);
  644.             if result then
  645.               s1:=s3;
  646.           end;
  647.           if not result then
  648.             checknum(s1,num,result);
  649.           if not result then
  650.             checkparam(s1,varsort,result);
  651.           if not result then
  652.             checkfunct(s1,s3,ffsort,result);
  653.           if not result then
  654.             check2varfunct(s1,s3,s4,ffsort,result);
  655.           if result then
  656.           begin
  657.           checknum(s2,num,result);
  658.           if result then
  659.             if (trunc(num)<>num) or (num<0) then
  660.           result:=false
  661.           else if trunc(num) in [2,3,4] then
  662.           begin
  663.             case trunc(num) of
  664.               2:fsort:=square;
  665.               3:fsort:=third;
  666.               4:fsort:=forth;
  667.             end;
  668.           end
  669.           else
  670.             result:=false;
  671.         end;
  672.       end;
  673.     end;
  674.     end;
  675.   until result or (i>=length(s)) or (j=0);
  676.   end;
  677. end;
  678.  
  679. procedure checkintpower(s:sstring;var s1,s2:sstring;var result:boolean);
  680. var s3,s4:sstring; i,j:integer; num:float; fsort:termsorttype;varsort:word;
  681. begin
  682.   result:=false;
  683.   i:=0;
  684.   repeat
  685.     j:=pos('^',copy(s,i+1,length(s)-i));
  686.     if j>0 then
  687.     begin
  688.       i:=i+j;
  689.     if (1<i) and (i<length(s)) then
  690.     begin
  691.       s1:=copy(s,1,i-1);
  692.       s2:=copy(s,i+1,length(s)-i);
  693.       checkbracketnum(s1,result);
  694.       if result then
  695.         checkbracketnum(s2,result);
  696.       if result then
  697.       begin
  698.       checkvar(s1,varsort,result);
  699.       if not result then
  700.         checkparam(s1,varsort,result);
  701.       if not result then
  702.       begin
  703.         checkbrack(s1,s3,result);
  704.         if result then
  705.           s1:=s3;
  706.       end;
  707.       if not result then
  708.          checknum(s1,num,result);
  709.       if not result then
  710.          checkfunct(s1,s3,fsort,result);
  711.       if not result then
  712.          check2varfunct(s1,s3,s4,fsort,result);
  713.       if result then
  714.       begin
  715.         checknum(s2,num,result);
  716.         if result then
  717.           if (trunc(num)<>num) then
  718.             result:=false
  719.           else if trunc(num) in [2,3,4] then
  720.             result:=false;
  721.       end;
  722.       end;
  723.     end;
  724.     end;
  725.   until result or (i>=length(s)) or (j=0);
  726. end;
  727.  
  728. procedure checkrealpower(s:sstring;var s1,s2:sstring;var result:boolean);
  729. var  i,j:integer; num:float; s3,s4:sstring; fsort:termsorttype;varsort:word;
  730. begin
  731.   result:=false;
  732.   i:=0;
  733.   repeat
  734.     j:=pos('^',copy(s,i+1,length(s)-i));
  735.     if j>0 then
  736.     begin
  737.       i:=i+j;
  738.     if (1<i) and (i<length(s)) then
  739.     begin
  740.       s1:=copy(s,1,i-1);
  741.       s2:=copy(s,i+1,length(s)-i);
  742.       checkbracketnum(s1,result);
  743.       if result then
  744.         checkbracketnum(s2,result);
  745.       if result then
  746.       begin
  747.       checkvar(s1,varsort,result);
  748.       if not result then
  749.         checkparam(s1,varsort,result);
  750.       if not result then
  751.         checknum(s1,num,result);
  752.       if not result then
  753.       begin
  754.         checkbrack(s1,s3,result);
  755.         if result then
  756.           s1:=s3;
  757.       end;
  758.       if not result then
  759.         checkfunct(s1,s3,fsort,result);
  760.       if not result then
  761.          check2varfunct(s1,s3,s4,fsort,result);
  762.       if result then
  763.       begin
  764.         checknum(s2,num,result);
  765.         if result then
  766.         begin
  767.           if (trunc(num)=num) then
  768.             result:=false; exit end;
  769.         checkvar(s2,varsort,result);if result then exit;
  770.         checkparam(s2,varsort,result); if result then exit;
  771.         checkbrack(s2,s3,result);
  772.         if result then begin
  773.             s2:=s3; exit; end;
  774.         checkfunct(s2,s3,fsort,result);if result then exit;
  775.         check2varfunct(s2,s3,s4,fsort,result);if result then exit;
  776.       end;
  777.       end;
  778.     end;
  779.     end;
  780.   until result or (i>=length(s)) or (j=0);
  781. end;
  782.  
  783.  
  784.  
  785. const maxlevels=20;  maxlevelsize=50;
  786.  
  787.  
  788.  
  789.  
  790. type
  791.  
  792.          termpointer=^termrec;
  793.  
  794.          operation1pointer=^operation1;
  795.  
  796.          termrec=record
  797.                  s:sstring;
  798.                  termsort:termsorttype;
  799.                  s1,s2:sstring;
  800.                  posit:array[1..3] of integer;
  801.                  next1,next2,prev:termpointer
  802.                  end;
  803.  
  804.  
  805.  
  806.          operation1=record
  807.                    theop:operationpointer;
  808.                    end;
  809.  
  810.  
  811.  
  812.  
  813.          levelsizearray=array[0..maxlevels] of integer;
  814.  
  815.   procedure ini(var theop:operationpointer;term:termsorttype);
  816.   begin
  817.     new(theop);
  818.     with theop^ do
  819.     begin
  820.       arg1:=nil; arg2:=nil; dest:=nil; next:=nil;
  821.       opnum:=ord(term);
  822.     end;
  823.   end;
  824.  
  825. procedure parsefunction(s:string;var fop:operationpointer;
  826.             var pointx,pointy,pointt,a,b,c,d,e:rpointer;var numop:integer;
  827.            var error:boolean; showprogress:boolean);
  828.  
  829. var result,done,found:boolean; code,l,i,levels,p:integer;
  830.       ab,levelsize:levelsizearray; s3,blanks:sstring;
  831.     firstterm,next1term,next2term,lastterm:termpointer; fsort:termsorttype;
  832.     matrix:array[0..maxlevels,1..maxlevelsize] of operation1pointer;
  833.     lastop:operationpointer;
  834.     num:float; varsort:word;
  835.  
  836.  
  837.  
  838. begin
  839.   error:=false;
  840.   new(pointx); new(pointy); new(pointt);
  841.   new(a); new(b); new(c); new(d); new(e);
  842.   blanks:=' ';
  843.   chopblanks(s);
  844.   repeat
  845.     checkbrack(s,s3,result);
  846.     if result then s:=s3;
  847.   until result=false;
  848.   done:=false;
  849.   levels:=0;
  850.   levelsize[0]:=1;
  851.   for l:=0 to maxlevels do
  852.     ab[l]:=0;
  853.   new(firstterm);
  854.   firstterm^.s:=s;
  855.   with firstterm^ do
  856.   begin
  857.     s1:=blanks; s2:=blanks; termsort:=variab;
  858.     next1:=nil; next2:=nil; prev:=nil;
  859.     new(matrix[0,1]);
  860.     new(matrix[0,1]^.theop);
  861.     with matrix[0,1]^.theop^ do
  862.     begin
  863.       arg1:=nil; arg2:=nil; dest:=nil;
  864.       opnum:=ord(variab); next:=nil;
  865.     end;
  866.   end;
  867.   lastterm:=firstterm;
  868.   lastterm^.posit[1]:=0;
  869.   lastterm^.posit[2]:=1;
  870.   lastterm^.posit[3]:=1;
  871.   repeat
  872.     code:=0;
  873.     repeat
  874.        l:=lastterm^.posit[1];
  875.        i:=lastterm^.posit[2];
  876.        if showprogress then write('.');
  877.       if lastterm^.next1=nil then
  878.       with lastterm^ do
  879.       begin
  880.         checkvar(s,varsort,result);
  881.         if result then
  882.         begin
  883.           termsort:=variab;
  884.           if varsort=1 then
  885.             if posit[3]=1 then matrix[l,i]^.theop^.arg1:=pointx
  886.               else matrix[l,i]^.theop^.arg2:=pointx
  887.           else if varsort=2 then
  888.             if posit[3]=1 then matrix[l,i]^.theop^.arg1:=pointy
  889.               else matrix[l,i]^.theop^.arg2:=pointy
  890.           else
  891.             if posit[3]=1 then matrix[l,i]^.theop^.arg1:=pointt
  892.               else matrix[l,i]^.theop^.arg2:=pointt;
  893.         end
  894.         else
  895.         begin
  896.           checkparam(s,varsort,result);
  897.           if result then
  898.           begin
  899.             termsort:=constant;
  900.             if varsort=1 then
  901.               if posit[3]=1 then matrix[l,i]^.theop^.arg1:=a
  902.                 else matrix[l,i]^.theop^.arg2:=a
  903.             else if varsort=2 then
  904.               if posit[3]=1 then matrix[l,i]^.theop^.arg1:=b
  905.                 else matrix[l,i]^.theop^.arg2:=b
  906.             else if varsort=3 then
  907.               if posit[3]=1 then matrix[l,i]^.theop^.arg1:=c
  908.                 else matrix[l,i]^.theop^.arg2:=c
  909.             else if varsort=4 then
  910.               if posit[3]=1 then matrix[l,i]^.theop^.arg1:=d
  911.                 else matrix[l,i]^.theop^.arg2:=d
  912.             else if varsort=5 then
  913.               if posit[3]=1 then matrix[l,i]^.theop^.arg1:=e
  914.                 else matrix[l,i]^.theop^.arg2:=e;
  915.           end
  916.           else
  917.           begin
  918.             checknum(s,num,result);
  919.             if result then
  920.             begin
  921.                termsort:=constant;
  922.               if posit[3]=1 then
  923.               begin
  924.                 new(matrix[l,i]^.theop^.arg1);
  925.                 matrix[l,i]^.theop^.arg1^:=num;
  926.               end else
  927.               begin
  928.                 new(matrix[l,i]^.theop^.arg2);
  929.                 matrix[l,i]^.theop^.arg2^:=num;
  930.               end;
  931.             end
  932.             else
  933.             begin
  934.               checkmin(s,s1,result);
  935.               if result then
  936.                 termsort:=minus
  937.               else
  938.               begin
  939.                 checksum(s,s1,s2,result);
  940.                 if result then
  941.                   termsort:=sum
  942.                 else
  943.                 begin
  944.                   checkdiff(s,s1,s2,result);
  945.                   if result then
  946.                     termsort:=diff
  947.                   else
  948.                   begin
  949.                     checkprod(s,s1,s2,result);
  950.                     if result then
  951.                       termsort:=prod
  952.                     else
  953.                     begin
  954.                       checkdiv(s,s1,s2,result);
  955.                       if result then
  956.                         termsort:=divis
  957.                       else
  958.                       begin
  959.                         checkfunct(s,s1,fsort,result);
  960.                         if result then
  961.                         begin
  962.                           termsort:=fsort;
  963.                         end
  964.                         else
  965.                         begin
  966.                           checkintpower(s,s1,s2,result);
  967.                           if result then
  968.                             termsort:=intpower
  969.                           else
  970.                           begin
  971.                             checkrealpower(s,s1,s2,result);
  972.                             if result then
  973.                               termsort:=realpower
  974.                             else
  975.                             begin
  976.                               check2varfunct(s,s1,s2,fsort,result);
  977.                               if result then
  978.                               begin
  979.                                 termsort:=fsort;
  980.                                 if fsort=randfunc then
  981.                                 begin
  982.                                   val(s1,num,code);
  983.                                   randomsize:=round(num);
  984.                                   randomiterates:=true;
  985.                                   randomize;
  986.                                 end;
  987.                                 if termsort=randrand then
  988.                                 begin
  989.                                   contrand:=true;
  990.                                   randomize;
  991.                                 end;
  992.                               end
  993.                               else
  994.                               begin
  995.                                 error:=true;
  996.                                 writeln('Syntax Error!');
  997.                                 exit;
  998.                               end;
  999.                             end;
  1000.                           end;
  1001.                         end;
  1002.                       end;
  1003.                     end;
  1004.                   end;
  1005.                 end;
  1006.               end;
  1007.             end;
  1008.           end;
  1009.         end;
  1010.       end; {with lastterm^}
  1011.       if lastterm^.termsort in [brack,minus,cosine,sine,expo,logar,
  1012.                           sqroot,arctang,square,third,forth,
  1013.                           abso,heavi,phase,hypersine,hypercosine] then
  1014.         begin
  1015.           new(next1term);
  1016.           l:=l+1;
  1017.           if l>maxlevels then
  1018.           begin
  1019.             writeln('Too many nestings!');
  1020.             error:=true; exit;
  1021.           end;
  1022.           if levels<l then
  1023.             levels:=l;
  1024.           i:=ab[l]+1;
  1025.           if i>maxlevelsize then
  1026.           begin
  1027.             writeln('Term too long, sorry!');
  1028.             error:=true; exit;
  1029.           end;
  1030.           with next1term^ do
  1031.           begin
  1032.             s:=lastterm^.s1;
  1033.             prev:=lastterm;
  1034.             posit[1]:=l;  posit[2]:=i; posit[3]:=1;
  1035.             termsort:=variab;
  1036.             s1:=blanks; s2:=blanks; num:=0;
  1037.              next1:=nil; next2:=nil;
  1038.              new(matrix[l,i]);
  1039.              ini(matrix[l,i]^.theop,lastterm^.termsort);
  1040.              p:=lastterm^.posit[3];
  1041.              new(matrix[l,i]^.theop^.dest);
  1042.              matrix[l,i]^.theop^.dest^:=0;
  1043.              if p=1 then
  1044.                matrix[lastterm^.posit[1],lastterm^.posit[2]]^.theop^.arg1:=
  1045.                            matrix[l,i]^.theop^.dest else
  1046.                matrix[lastterm^.posit[1],lastterm^.posit[2]]^.theop^.arg2:=
  1047.                            matrix[l,i]^.theop^.dest;
  1048.            end;
  1049.           lastterm^.next1:=next1term;
  1050.           ab[l]:=ab[l]+1;
  1051.         end;
  1052.       if lastterm^.termsort in
  1053.                  [sum,diff,prod,divis,intpower,realpower,maxim,minim,
  1054.                  randfunc,argu,radius,randrand] then
  1055.         begin
  1056.           if lastterm^.next1=nil then
  1057.           begin
  1058.             new(next1term);
  1059.             l:=l+1;
  1060.             if l>maxlevels then
  1061.             begin
  1062.               writeln('Too many nestings!');
  1063.               error:=true; exit;
  1064.             end;
  1065.             if levels<l then
  1066.               levels:=l;
  1067.             i:=ab[l]+1;
  1068.             if i>maxlevelsize then
  1069.             begin
  1070.               writeln('Term too long, sorry!');
  1071.               error:=true; exit;
  1072.             end;
  1073.             with next1term^ do
  1074.             begin
  1075.               s:=lastterm^.s1;
  1076.               prev:=lastterm;
  1077.               posit[1]:=l;
  1078.               posit[2]:=i; posit[3]:=1;
  1079.               num:=0;
  1080.               s1:=blanks; s2:=blanks; termsort:=variab;
  1081.               next1:=nil; next2:=nil;
  1082.               new(matrix[l,i]);
  1083.               ini(matrix[l,i]^.theop,lastterm^.termsort);
  1084.               p:=lastterm^.posit[3];
  1085.               new(matrix[l,i]^.theop^.dest);
  1086.               matrix[l,i]^.theop^.dest^:=0;
  1087.               if p=1 then
  1088.                matrix[lastterm^.posit[1],lastterm^.posit[2]]^.theop^.arg1:=
  1089.                            matrix[l,i]^.theop^.dest else
  1090.                matrix[lastterm^.posit[1],lastterm^.posit[2]]^.theop^.arg2:=
  1091.                            matrix[l,i]^.theop^.dest;
  1092.             end;
  1093.             lastterm^.next1:=next1term;
  1094.           end
  1095.           else
  1096.           begin
  1097.             new(next2term);
  1098.             l:=l+1;
  1099.             if l>maxlevels then
  1100.             begin
  1101.               writeln('Too many nestings!');
  1102.               error:=true; exit;
  1103.             end;
  1104.             if levels<l then
  1105.               levels:=l;
  1106.             i:=ab[l]+1;
  1107.             if i>maxlevelsize then
  1108.             begin
  1109.               writeln('Term too long, sorry!');
  1110.               error:=true; exit;
  1111.             end;
  1112.             with next2term^ do
  1113.             begin
  1114.               s:=lastterm^.s2;
  1115.               prev:=lastterm;
  1116.               posit[1]:=l; posit[2]:=i; posit[3]:=2;
  1117.               num:=0;
  1118.               s1:=blanks; s2:=blanks; termsort:=variab;
  1119.               next1:=nil; next2:=nil;
  1120.             end;
  1121.             lastterm^.next2:=next2term;
  1122.             ab[l]:=ab[l]+1;
  1123.           end;
  1124.         end;
  1125.       if lastterm^.next1=nil then
  1126.         code:=1
  1127.       else
  1128.         if lastterm^.next2=nil then
  1129.           lastterm:=lastterm^.next1
  1130.         else
  1131.           lastterm:=lastterm^.next2;
  1132.    until code=1;
  1133.    if lastterm=firstterm then
  1134.    begin
  1135.      done:=true;
  1136.      dispose(lastterm);
  1137.      firstterm:=nil;
  1138.    end
  1139.    else
  1140.    begin
  1141.      repeat
  1142.        if lastterm^.next1<>nil then
  1143.          dispose(lastterm^.next1);
  1144.        if lastterm^.next2<>nil then
  1145.          dispose(lastterm^.next2);
  1146.        lastterm:=lastterm^.prev;
  1147.      until ((lastterm^.termsort in [sum,diff,prod,divis,intpower,realpower,
  1148.                   maxim,minim,randfunc,argu,radius,randrand])
  1149.              and
  1150.             (lastterm^.next2=nil)) or (lastterm=firstterm);
  1151.      if (lastterm=firstterm) and ((firstterm^.termsort in [brack,minus,cosine,sine,
  1152.                 expo,logar,sqroot,arctang,square,third,forth,
  1153.                 abso,heavi,phase,hypersine,hypercosine])
  1154.                    or ((firstterm^.termsort in [sum,diff,prod,divis,intpower,
  1155.                       realpower,maxim,minim,randfunc,argu,radius,randrand])
  1156.                        and (firstterm^.next2<>nil))) then
  1157.          done:=true;
  1158.    end;
  1159.  until done;
  1160.  if firstterm<>nil then
  1161.  begin
  1162.    if firstterm^.next1<>nil then dispose(firstterm^.next1);
  1163.    if firstterm^.next2<>nil then dispose(firstterm^.next2);
  1164.    dispose(firstterm);
  1165.  end;
  1166.  for l:=1 to levels do
  1167.    levelsize[l]:=ab[l];
  1168.  if levels=0 then
  1169.  begin
  1170.    fop:=matrix[0,1]^.theop;
  1171.    fop^.dest:=fop^.arg1;
  1172.    numop:=0;
  1173.    dispose(matrix[0,1]);
  1174.  end
  1175.  else
  1176.  begin
  1177.    for l:=levels downto 1 do
  1178.    for i:=1 to levelsize[l] do
  1179.    begin
  1180.      if (l=levels) and (i=1) then
  1181.      begin
  1182.        numop:=1;
  1183.        fop:=matrix[l,i]^.theop;
  1184.        lastop:=fop;
  1185.        dispose(matrix[l,i]);
  1186.      end
  1187.      else
  1188.      begin
  1189.        inc(numop);
  1190.        lastop^.next:=matrix[l,i]^.theop;
  1191.        lastop:=lastop^.next;
  1192.        dispose(matrix[l,i]);
  1193.      end;
  1194.    end;
  1195.    with matrix[0,1]^.theop^ do
  1196.    begin
  1197.      arg1:=nil; arg2:=nil; dest:=nil;
  1198.    end;
  1199.    dispose(matrix[0,1]^.theop);
  1200.    dispose(matrix[0,1]);
  1201.  end;
  1202. end;
  1203. end.